/*
 * @Author: chenbolin@msn.cn
 * @Date: 2023-10-25 18:55:03
 * @LastEditors: chenbolin@msn.cn
 * @LastEditTime: 2023-10-28 11:09:37
 * @FilePath: \Remote\src\App\LED.c
 * @Description:
 *
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */
#include "LED.h"
#include "Sys.h"

typedef struct
{
    LEDState_t state;
    LEDColor_t color;
    uint8_t pin[LED_COLOR_COUNT];
    uint8_t level;
    uint32_t interval;
    SysTime_t flipTime;
} LEDStateCtrl_t;

static LEDStateCtrl_t g_stateCtrl[LED_ID_COUNT];

static void ledStateHandle(void)
{
    LEDStateCtrl_t *ctrl;
    uint8_t i;

    for (i = 0; i < LED_ID_COUNT; i++)
    {
        ctrl = &g_stateCtrl[i];
        if (ctrl->interval != 0 && SysTimeHasPast(ctrl->flipTime, ctrl->interval))
        {
            ctrl->level = !ctrl->level;
            HalGPIOSetLevel(ctrl->pin[ctrl->color], ctrl->level);
            ctrl->flipTime = SysTime();
        }
    }
}

void LEDStateSet(LEDID_t id, LEDColor_t color, LEDState_t state)
{
    LEDStateCtrl_t *ctrl;
    uint8_t i;

    if (id < LED_ID_COUNT)
    {
        ctrl = &g_stateCtrl[id];
        if (ctrl->state != state || color != ctrl->color)
        {
            switch (state)
            {
            case LED_STATE_OFF:
            case LED_STATE_ON:
                ctrl->interval = 0;
                break;
            case LED_STATE_BLINK_SLOW:
                ctrl->interval = 500;
                break;
            case LED_STATE_BLINK_FAST:
                ctrl->interval = 100;
                break;
            }
            ctrl->state = state;
            ctrl->color = color;
            ctrl->level = (state == LED_STATE_ON); // 只有常亮是高电平，其他都是低电平开始
            ctrl->flipTime = SysTime();

            for (i = 0; i < LED_COLOR_COUNT; i++)
            {
                HalGPIOSetLevel(ctrl->pin[i], 0);
            }
            HalGPIOSetLevel(ctrl->pin[color], ctrl->level);
        }
    }
}

void LEDInitialize(void)
{
    memset(&g_stateCtrl, 0, sizeof(LEDStateCtrl_t));
    g_stateCtrl[LED_ID_POWER].pin[LED_COLOR_RED] = HAL_PIN_OUT_LED_POWER_RED;
    g_stateCtrl[LED_ID_POWER].pin[LED_COLOR_GREEN] = HAL_PIN_OUT_LED_POWER_GREEN;
    g_stateCtrl[LED_ID_SIGNAL].pin[LED_COLOR_RED] = HAL_PIN_OUT_LED_SIGNAL_RED;
    g_stateCtrl[LED_ID_SIGNAL].pin[LED_COLOR_GREEN] = HAL_PIN_OUT_LED_SIGNAL_GREEN;
}

void LEDPoll(void)
{
    ledStateHandle();
}
